/*
 * @Author: chenbolin@msn.cn
 * @Date: 2023-10-06 10:52:06
 * @LastEditors: chenbolin@msn.cn
 * @LastEditTime: 2023-10-28 11:34:37
 * @FilePath: \Receiver\src\App\UserMain.c
 * @Description:
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
 */
#include "UserMain.h"
#include "Sys.h"
#include "Remote.h"
#include "LED.h"

static const HalPWMIO_t PWM_OUT_IOs[SYS_VALVE_CH_COUNT][2] = {
    {{GPIOB, GPIO_PIN_8}, {GPIOB, GPIO_PIN_7}},  // 大臂伸,缩
    {{GPIOE, GPIO_PIN_0}, {GPIOB, GPIO_PIN_9}},  // 大臂升,降
    {{GPIOD, GPIO_PIN_1}, {GPIOD, GPIO_PIN_0}},  // 转台顺,逆
    {{GPIOE, GPIO_PIN_6}, {GPIOE, GPIO_PIN_5}}}; // 吊钩升,降

static bool g_emergencyStop = false;

/*同步接收器的数据给遥控器*/
static void toRemote(void)
{
    static SysTime_t lastSendTime = 0;
    uint8_t authorized;

    if (SysTimeHasPast(lastSendTime, SYS_PERIODIC_EXECUTION_INTERVAL))
    {
        authorized = SysIsAuthorized();
        RemoteDataSend((uint8_t *)&authorized, 1);
        lastSendTime = SysTime();
    }
}

static void emergencyEnd(void *args)
{
    HalGPIOSetLevel(HAL_PIN_OUT_ENGINE_STOP, 0); // 释放熄火控制
}

static void emergencyStopHandle(void)
{
    uint8_t i;

    if (RemoteGetButtonLevel(REMOTE_BTN_ID_EMERGENCY_STOP))
    {
        if (!g_emergencyStop)
        {
            /*停止动作*/
            for (i = 0; i < SYS_VALVE_CH_COUNT; i++)
            {
                HalPWMDutySet(i * 2, 0);
                HalPWMDutySet(i * 2 + 1, 0);
            }
            RemoteReset();
            SysThrottleReset();                              // 油门清零
            HalGPIOSetLevel(HAL_PIN_OUT_ENGINE_STOP, 1);     // 熄火
            SysDelayProcessRegist(5000, emergencyEnd, NULL); // 5秒后释放熄火控制
            g_emergencyStop = true;
        }
    }
    else
    {
        g_emergencyStop = false;
    }
}

static void doPWMDutySet(SysValveChannel_t ch, int16_t duty)
{
    HalPWMDutySet(ch * 2 + SYS_JOYSTICK_DIR_UP, duty > 0 ? duty : 0);
    HalPWMDutySet(ch * 2 + SYS_JOYSTICK_DIR_DOWN, duty < 0 ? -duty : 0);
}

static void actionsHandle(void)
{
    static SysTime_t lastTime = 0;
    RemoteData_t *rdata;
    uint8_t i;
//    int symb;

    if (SysTimeHasPast(lastTime, 50))
    {
        emergencyStopHandle();

        rdata = RemoteDataGet();

        HalGPIOSetLevel(HAL_PIN_OUT_EMERGENCY_STOP, g_emergencyStop);
        HalGPIOSetLevel(HAL_PIN_OUT_LIGTING, RemoteGetButtonLevel(REMOTE_BTN_ID_LIGHT));
        HalGPIOSetLevel(HAL_PIN_OUT_HORN, RemoteGetButtonLevel(REMOTE_BTN_ID_HORN));
        HalGPIOSetLevel(HAL_PIN_OUT_ENGINE_START, RemoteGetButtonLevel(REMOTE_BTN_ID_START));
        HalGPIOSetLevel(HAL_PIN_OUT_ENGINE_STOP, RemoteGetButtonLevel(REMOTE_BTN_ID_STOP));

        SysSetValveFrequency(rdata->frequency); // 更新比例阀频率

        for (i = 0; i < SYS_VALVE_CH_COUNT; i++)
        {
            doPWMDutySet((SysValveChannel_t)i, rdata->current[i]);
        }

        LEDStateSet(LED_ID_SIGNAL, LED_COLOR_GREEN, RemoteDisconnected() ? LED_STATE_OFF : LED_STATE_ON);
        lastTime = SysTime();
    }
}

static void receiverPeriodicProcess(void)
{
    toRemote();
    actionsHandle();
}

static void pwmChannelInit(void)
{
    uint8_t i;
    for (i = 0; i < SYS_VALVE_CH_COUNT; i++)
    {
        HalPWMChannelStart(i * 2, 0, PWM_OUT_IOs[i][0].port, PWM_OUT_IOs[i][0].pin);
        HalPWMChannelStart(i * 2 + 1, 0, PWM_OUT_IOs[i][1].port, PWM_OUT_IOs[i][1].pin);
    }
}

void UserMainInitialize(void)
{
    RemoteInitialize();
    pwmChannelInit();
    LEDInitialize();
    LEDStateSet(LED_ID_STATE, LED_COLOR_GREEN, LED_STATE_BLINK_SLOW); // 状态灯一直慢闪
}

void UserMainPoll(void)
{
    receiverPeriodicProcess();
    RemotePoll();
    LEDPoll();
}
